using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public class ScriptedEventGodzilla : ScriptedEvent
    {
        public ScriptedEventGodzilla(WorldProperties worldProperties)
            : base(worldProperties)
        {
            
        }

        protected const double SCRIPT_START_TIME_SECONDS = 300;

        protected const int APPEAR_NUMBER_OF_FRAMES_TO_PLAY = 8;
        protected const int APPEAR_FRAMES_PER_SECOND = 6;
        Vector2 spawnPosition = Vector2.Zero;
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            // 5:00 - endgame!
            if (state == 0)
            {
                if (gameTime.TotalGameTime.Subtract(worldProperties.PauseTime).TotalSeconds >= SCRIPT_START_TIME_SECONDS) state = 1;

            }
            else if (state == 1)
            {
                // write the text warning of his approach
                worldProperties.DrawTextWarning("Game over man, game over!", 2100);
                state = 2;

            }
            else if (state == 2)
            {
                if (gameTime.TotalGameTime.Subtract(worldProperties.PauseTime).TotalSeconds >= SCRIPT_START_TIME_SECONDS + 1.5) state = 3;

            }
            else if (state == 3)
            {
                // show the appearing animation/effect
                spawnPosition = GetSpawnPosition(90);
                new Animation(worldProperties,
                    spawnPosition, 0, new Vector2(90, 90), 1.0f,
                    APPEAR_NUMBER_OF_FRAMES_TO_PLAY, APPEAR_FRAMES_PER_SECOND, "Sprites\\scripted_godzilla_appear");
                state = 4;

            }
            else if (state == 4)
            {
                if (gameTime.TotalGameTime.Subtract(worldProperties.PauseTime).TotalSeconds >= SCRIPT_START_TIME_SECONDS + 2) state = 5;

            }
            else if (state == 5)
            {
                foreach (EnemyUnit enemy in worldProperties.Enemies)
                {
                    enemy.Kill();
                    new Animation(worldProperties,
                        enemy.Position, enemy.Rotation, new Vector2(10, 50), 1.0f,
                        4, 4, "Sprites\\scripted_godzilla_killall_bg");
                    new Animation(worldProperties,
                        enemy.Position, enemy.Rotation, new Vector2(35, 50), 1.0f,
                        4, 4, "Sprites\\scripted_godzilla_killall_fg");
                }
                worldProperties.Spawning = false;
                // spawn the unit
                // he will handle spawning correctly
                EnemyUnitBigBoss unitBoss = new EnemyUnitBigBoss(worldProperties, EnemyKind.BigBoss);
                // give it a spawn position
                unitBoss.Position = spawnPosition;
                // set the rotation to face them in towards the map
                Vector2 vectorToCenter = new Vector2(worldProperties.Map.WorldBounds.Center.X, worldProperties.Map.WorldBounds.Center.Y) - unitBoss.Position;
                unitBoss.Rotation = (float)Math.Atan2(vectorToCenter.Y, vectorToCenter.X);
                worldProperties.Enemies.Add(unitBoss);

                state = 6;
            }
            else if (state == 6)
            {
                Game.Components.Remove(this);
            }
        }

        public Vector2 GetSpawnPosition(float distanceFromEdge)
        {
            Vector2 position;

            // spawn him on one of the two sides furthest away from a tower (still a little random)
            float leftSideDistance = float.PositiveInfinity;
            float topSideDistance = float.PositiveInfinity;
            float rightSideDistance = float.PositiveInfinity;
            float bottomSideDistance = float.PositiveInfinity;
            foreach (Player player in worldProperties.Players)
            {
                foreach (Tower tower in player.Towers)
                {
                    leftSideDistance = Math.Min(tower.Position.X, leftSideDistance);
                    topSideDistance = Math.Min(tower.Position.Y, leftSideDistance);
                    rightSideDistance = Math.Min(1024 - tower.Position.X, leftSideDistance);
                    bottomSideDistance = Math.Min(768 - tower.Position.Y, leftSideDistance);
                }
            }
            List<float> sides = new List<float>();
            sides.Add(leftSideDistance);
            sides.Add(topSideDistance);
            sides.Add(rightSideDistance);
            sides.Add(bottomSideDistance);
            sides.Sort();
            sides.Reverse();
            float sideToUse = sides.ElementAt<float>(worldProperties.Random.Next(1));
            if (leftSideDistance == sideToUse)
            {
                // left
                position = new Vector2(distanceFromEdge,
                    MathHelper.Lerp(distanceFromEdge, 768 - distanceFromEdge, (float)worldProperties.Random.NextDouble()));
            }
            else if (topSideDistance == sideToUse)
            {
                // top
                position = new Vector2(MathHelper.Lerp(distanceFromEdge, 1024 - distanceFromEdge, (float)worldProperties.Random.NextDouble()),
                    distanceFromEdge);
            }
            else if (rightSideDistance == sideToUse)
            {
                // right
                position = new Vector2(1024 - distanceFromEdge,
                    MathHelper.Lerp(distanceFromEdge, 768 - distanceFromEdge, (float)worldProperties.Random.NextDouble()));
            }
            else
            {
                // bottom
                position = new Vector2(MathHelper.Lerp(distanceFromEdge, 1024 - distanceFromEdge, (float)worldProperties.Random.NextDouble()),
                    768 - distanceFromEdge);
            }

            return position;
        }
    }
}